/*
 * @Descripttion:
 * @Author: lx
 * @Date: 2022-03-23 14:03:57
 * @LastEditTime: 2022-06-29 15:44:16
 */

// 函子
class Container {
    static Of(value) {
        return new Container(value);
    }

    constructor(value) {
        this._value = value;
    }

    map(fn) {
        return Container.Of(fn(this._value));
    }
}

const c = new Container(5).map((i) => i * i);
console.log(c);

// maybe函子
// 如果value是null或者undefined直接返回，否则执行方法
class Maybe {
    static Of(value) {
        return new Maybe(value);
    }

    constructor(value) {
        this._value = value;
    }

    isNull() {
        return this._value === undefined || this._value === null;
    }

    map(fn) {
        return Maybe.Of(this.isNull() ? null : fn(this._value));
    }
}

const m = new Maybe(null).map((i) => i * i);
console.log(m);

// Either 函子、

class Left {
    static Of(value) {
        return new Left(value);
    }

    constructor(value) {
        this._value = value;
    }

    map() {
        return this;
    }
}

class Right {
    static Of(value) {
        return new Right(value);
    }

    constructor(value) {
        this._value = value;
    }

    map(fn) {
        return Right.Of(fn(this._value));
    }
}

const jsonparse = (str) => {
    try {
        return Right.Of(JSON.parse(str));
    } catch (e) {
        return Left.Of({error: e.message});
    }
};

let r = jsonparse('{ "name": "zs" }').map((x) => x.name.toUpperCase());
console.log(r);

// IO函子   把不纯的动作变成纯的
const fp = require("lodash/fp");

class IO {
    static of(x) {
        return new IO(function () {
            return x;
        });
    }

    constructor(fn) {
        this._value = fn;
    }

    map(fn) {
        return new IO(fp.flowRight(fn, this._value));
    }
}

let io = IO.of(process).map((p) => p);
console.log(io._value());
